#include "Plane.h"

Plane::Plane()
{
}

Plane::Plane(int w, int h, float tileSize)
	:Model()
	, width(w)
	, height(h)
	, tileSize(tileSize)
	, currentTime(0)
{
	transform = Transform3D(0.f, -2.0f, 0.f, 15.f, 0.f, 0.f);

	numVertices = (++w) * (++h);
	numFaces = w * h * 2;

	BuildVertexBuffer();
	BuildIndexBuffer();

	HR(D3DXCreateEffectFromFile(gD3DDevice, "Transform.fx", 0, 0, D3DXSHADER_DEBUG, 0, &mFX, &mErrors));
	if (mErrors)
	{
		MessageBox(0, (char*)mErrors->GetBufferPointer(), 0, 0);
	}

	mhTech = mFX->GetTechniqueByName("TransformColorWaveTech");
	mFX->SetTechnique(mhTech);

	mhWVP = mFX->GetParameterByName(0, "gWVP");
	mhTime = mFX->GetParameterByName(0, "gTime");
}

Plane::~Plane()
{
}

void Plane::BuildVertexBuffer()
{
	HR(gD3DDevice->CreateVertexBuffer(numVertices*sizeof(VertexPosCol), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &mVB, 0));
	VertexPosCol* vertices = 0;
	HR(mVB->Lock(0, 0, (void**)&vertices, 0));

	// Check -1
	float halfWidth = (width - 1) * tileSize * 0.5f;
	float halfHeight = (height - 1) * tileSize * 0.5f;

	for (int i = 0; i < width; i++)
	{
		float z = halfHeight - i * tileSize;
		for (int j = 0; j < height; j++)
		{
			float x = -halfWidth + j * tileSize;
			float y = 0.0f;
			vertices[i * height + j].pos = D3DXVECTOR3(x, y, z);
			vertices[i * height + j].col = D3DCOLOR_XRGB(128, 128, 128);
		}
	}
	mVB->Unlock();
}

void Plane::BuildIndexBuffer()
{
	//Check it!
	HR(gD3DDevice->CreateIndexBuffer((width * height * 6) * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &mIB, 0));

	WORD* indices = 0;
	HR(mIB->Lock(0, 0, (void**)&indices, 0));
	int k = 0;
	for (int i = 0; i < width - 1; ++i)
	{
		for (int j = 0; j < height - 1; ++j)
		{
			indices[k] = i * height + j;
			indices[k+1] = i * height + (j+1);
			indices[k+2] = (i + 1) * height + j;
			indices[k+3] = (i + 1) * height + j;
			indices[k+4] = i * height + (j+1);
			indices[k+5] = (i+1) * height + (j+1);
			k += 6; // NextQuad
		}
	}
	HR(mIB->Unlock());
}

void Plane::Update(float dt)
{
	currentTime += dt;
}

void Plane::Draw(ID3DXSprite* sprite, D3DXMATRIX& view, D3DXMATRIX& proj)
{
	HR(gD3DDevice->SetStreamSource(0, mVB, 0, sizeof(VertexPosCol)));
	HR(gD3DDevice->SetVertexDeclaration(VertexPosCol::decl));
	HR(gD3DDevice->SetIndices(mIB));

	D3DXMATRIX world;
	D3DXMatrixIdentity(&world);
	D3DXMATRIX rotation;
	transform.MatrixRotation(rotation);
	D3DXMATRIX translation;
	transform.MatrixTranslation(translation);

	HR(mFX->SetFloat(mhTime, currentTime));
	HR(mFX->SetMatrix(mhWVP, &(world * translation * view * proj)));

	UINT numPasses = 0;
	HR(mFX->Begin(&numPasses, 0));
	for (UINT i = 0; i < numPasses; i++)
	{
		HR(mFX->BeginPass(i));
		HR(gD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVertices, 0, numFaces));
		HR(mFX->EndPass());
	}
	HR(mFX->End());
}

